/**
 * 
 */
package fr.cephb.io;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * This class is used to given a temporary
 * place to write some data and to be able to
 * remove the file at the end.
 * For example it is used to write the content of a zip file during
 * the processing of a Servlet. If the servlet is ok, we dump the content of this
 * object to the client, finally at the end we delete the content of this object.
 *
 */
public class TmpWriter
	extends Writer
	{
	private File tmpFile;
	private PrintWriter out=null;
	private long length=0L;
	/** constructor with a given tmp dir */
	public TmpWriter(File directory) throws IOException
		{
		this.tmpFile= File.createTempFile("tmp", ".data", directory);
		this.out= new PrintWriter(new FileWriter(this.tmpFile));
		}
	
	/** constructor with the default tmp dir */
	public TmpWriter() throws IOException
		{
		this(new File(System.getProperty("java.io.tmpdir", "/tmp")));
		}
	/** finalize call delete() at the end */
	@Override
	protected void finalize() throws Throwable {
		try {
			delete();
		} catch (Exception e) {
			
			}
		super.finalize();
		}
	
	
	
	/** delegate flush */
	@Override
	public void flush() throws IOException {
		if(out!=null) out.flush();
		}
	
	/** delegate close */
	public void close() throws IOException
		{
		flush();
		if(out!=null) out.close();
		}
	
	
	/** delegate println */
	public void println(String s) throws IOException
		{
		print(s);
		println();
		}
	
	/** delegate println */
	public void print(String s) throws IOException
		{
		if(s==null) s="null";
		write(s.toCharArray());
		}
	
	/** delegate println */
	public void println() throws IOException
		{
		print("\n");
		}
	
	/** delegate print */
	public void print(int s) throws IOException
		{
		print(String.valueOf(s));
		}
	
	/** delegate println */
	public void println(int s) throws IOException
		{
		print(s);
		println();
		}
	
	/** delegate print */
	public void print(long s) throws IOException
		{
		print(String.valueOf(s));
		}
	/** delegate println */
	public void println(long s) throws IOException
		{
		print(s);
		println();
		}
	
	/** delegate print */
	public void print(double s) throws IOException
		{
		print(String.valueOf(s));
		}
	/** delegate println */
	public void println(double s) throws IOException
		{
		print(s);
		println();
		}
	/** delegate print */
	public void print(float s) throws IOException
		{
		print(String.valueOf(s));
		}
	/** delegate println */
	public void println(float s) throws IOException
		{
		print(s);
		println();
		}
	
	/** delegate print */
	public void print(boolean s) throws IOException
		{
		print(String.valueOf(s));
		}
	/** delegate println */
	public void println(boolean s) throws IOException
		{
		print(s);
		println();
		}

	/** delegate print */
	public void print(Object s) throws IOException
		{
		print(String.valueOf(s));
		}
	/** delegate println */
	public void println(Object s) throws IOException
		{
		print(s);
		println();
		}
	
	
	@Override
	/** delegate write */
	public void write(char[] cbuf, int off, int len) throws IOException
		{
		if(this.out==null) throw new IOException("stream was closed");
		this.out.write(cbuf, off, len);
		this.length+=len;
		}
	
	
	
	@Override
	/** delegate write */
	public void write(char b[]) throws IOException
		{
		write(b,0,b.length);
		}
	
	@Override
	/** delegate write */
	public void write(String s) throws IOException
		{
		write(s.toCharArray());
		}
	/** return the number of bytes that have been writeen so far */
	public long getSize()
		{
		return this.length;
		}
	
	/** return true if no byte has been written */
	public boolean isEmpty()
		{
		return getSize()==0L;
		}
	
	/** call 'close()' and copy the content of this object to 
	 * a ZipOutputStream
	 * @param zout the zip
	 * @param entryName the name of the entry
	 * @throws IOException
	 */
	public void copyToZip(ZipOutputStream zout,String entryName)  throws IOException
		{
		close();
		ZipEntry entry= new ZipEntry(entryName);
		zout.putNextEntry(entry);
		if(!isEmpty() && this.tmpFile.exists())
			{
			InputStream in= new FileInputStream(this.tmpFile);
			IOUtils.copyTo(in, zout);
			in.close();
			}
		zout.flush();
		zout.closeEntry();
		delete();
		}
	
	@Override
	public boolean equals(Object obj)
		{
		return this==obj;
		}
	
	/** delete the tmp file */
	public void delete()
		{
		if(this.tmpFile.exists())  this.tmpFile.delete();
		}
	
	@Override
	public int hashCode() {
		return this.tmpFile==null?-1:this.tmpFile.hashCode();
		}
	
	@Override
	public String toString() {
		return getClass().getName()+":"+this.tmpFile;
		}
	}
